home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 43.zip / Sources C- WorkDisk III.adf / vsprite.c < prev    next >
C/C++ Source or Header  |  1987-02-19  |  20KB  |  500 lines

  1. /* vsprite.final.c, merged with its support files */
  2. /* execute makesimple vsprite.final ; Amiga C 1.1 (Lattice 3.03) */
  3. #include "exec/types.h"
  4. #include "intuition/intuition.h"
  5. #include "graphics/sprite.h"
  6. #include "exec/memory.h"
  7. #include "graphics/gels.h"
  8. /* ask system to create and manage MAXSP vsprites */
  9. #define MAXSP 28
  10. /* define possible speeds for vsprites in counts per vblank */
  11. SHORT speed[] = { 1, 2, -1, -2 };
  12. SHORT xmove[MAXSP], ymove[MAXSP];
  13.                                 /* sprite directions of movement */
  14. struct VSprite *vsprite[MAXSP]; /* MAXSP simple sprites */
  15. struct VSprite *vspr;           /* pointer to a sprite */
  16. short maxgot;                   /* max # of sprites we created */
  17. struct GelsInfo mygelsinfo;     /* the window's RastPort needs one
  18.                                  * of these in order to do VSprites */
  19. struct Window *w;       /* pointer to a Window   */
  20. struct RastPort *rp;    /* pointer to a RastPort */
  21. struct Screen *s;       /* a pointer to a Screen */
  22. struct ViewPort *vp;    /* pointer to a ViewPort */
  23. struct Window *OpenWindow();
  24. struct Screen *OpenScreen();
  25. LONG GfxBase;
  26. LONG IntuitionBase;
  27. /* 18 words of sprite data = 9 lines of sprite data */
  28. UWORD sprite_data[ ] = {
  29.                         0x0fc3, 0x0000, /* image data line 1*/
  30.                         0x3ff3, 0x0000, /* image data line 2*/
  31.                         0x30c3, 0x0000, /* image data line 3*/
  32.                         0x0000, 0x3c03, /* image data line 4*/
  33.                         0x0000, 0x3fc3, /* image data line 5*/
  34.                         0x0000, 0x03c3, /* image data line 6*/
  35.                         0xc033, 0xc033, /* image data line 7*/
  36.                         0xffc0, 0xffc0, /* image data line 8*/
  37.                         0x3f03, 0x3f03, /* image data line 9*/
  38.                         };
  39. UWORD *sprdata;
  40. movesprites()
  41. {
  42.         short i;
  43.         for (i=0; i<maxgot; i++)
  44.         {
  45.                 vspr = vsprite[i];
  46.                 vspr->X = xmove[i]+vspr->X;
  47.                 vspr->Y = ymove[i]+vspr->Y;
  48.                 /* move the sprites ... here. */
  49.                 if(vspr->X >= 300 || vspr->X <= 0) xmove[i]=-xmove[i];
  50.                 if(vspr->Y >= 190 || vspr->Y <= 0) ymove[i]=-ymove[i];
  51.  
  52.         }
  53.         SortGList(rp);  /* get the list in order */
  54.         DrawGList(rp, vp);      /* create the sprite instructions */
  55.         MakeScreen(s);  /* ask Intuition to pull it all together */
  56.         RethinkDisplay(); /* and to show us what we have now. */
  57. }
  58. #define AZCOLOR 1
  59. #define WHITECOLOR 2
  60. #define WC WINDOWCLOSE
  61. #define WS WINDOWSIZING
  62. #define WDP WINDOWDEPTH
  63. #define WDR WINDOWDRAG
  64. #define NORMALFLAGS (WC|WS|WDP)
  65. /* Did not use windowdrag because dont want screen to be moved. */
  66. /* Allow window sizing so user can decrease size of window, then
  67.  * increase it again, thus erasing the background text and more
  68.  * easily see that some vsprites wink out and into existence when
  69.  * too many sprites are on a single horizontal plane and the
  70.  * vsprite machine runs out of sprites to assign.
  71.  */
  72. /* myfont1 specifies characteristics of the default font;
  73.  * this case selects the 80 column font that displays as
  74.  * 40 columns in low resolution mode.
  75.  */
  76. struct TextAttr myfont1 = { "topaz.font", 8, 0, 0 };
  77.  
  78. struct NewScreen myscreen1 = {
  79.         0, 0,           /* LeftEdge, TopEdge ... where to put screen */
  80.         320, 200,       /* Width, Height ... size of the screen */
  81.         5,              /* 5 planes Depth, means 2 to the 5th or
  82.                         * 32 different colors to choose from once
  83.                         * the screen is opened.
  84.                         */
  85.         1, 0,           /* DetailPen, BlockPen */
  86.         SPRITES,        /* ViewModes ... value of 0 = low resolution */
  87.         CUSTOMSCREEN,   /* Type of screen */
  88.         &myfont1,       /* Font to be used as default for this screen */
  89.         "32 Color Test", /* DefaultTitle for its title bar */
  90.         NULL,           /* screens user-gadgets, always NULL, ignored */
  91.         NULL };
  92.                         /* address of custom bitmap for screen,
  93.                          * not used in this example
  94.                          */
  95. struct NewWindow myWindow = {
  96.         0,              /* LeftEdge for window measured in pixels,
  97.                            at the current horizontal resolution,
  98.                            from the leftmost edge of the Screen */
  99.         0,              /* TopEdge for window is measured in lines
  100.                            from the top of the current Screen.   */
  101.         320, 185,       /* Width, Height of this window */
  102.         0,              /* DetailPen - what pen number is to be
  103.                            used to draw the borders of the window */
  104.         1,              /* BlockPen - what pen number is to be
  105.                            used to draw system generated window
  106.                            gadgets */
  107.                         /* (for DetailPen and BlockPen, the value
  108.                             of -1 says "use the default value")  */
  109.         CLOSEWINDOW,    /* simplesprite program used INTUITICKS also */
  110.                         /* IDCMP Flags */
  111.         NORMALFLAGS | GIMMEZEROZERO | ACTIVATE,
  112.                         /* Window Flags:  (see below for more info) */
  113.         NULL,           /* FirstGadget */
  114.         NULL,           /* CheckMark   */
  115.         "Click Close Gadget To Stop",   /* Window title */
  116.         NULL,           /* Pointer to Screen if not workbench */
  117.         NULL,           /* Pointer to BitMap if a SUPERBITMAP window */
  118.         320, 10,        /* minimum width, minimum height */
  119.         320, 200,       /* maximum width, maximum height */
  120.         CUSTOMSCREEN
  121.         };
  122. #include "graphics/gfxmacros.h"
  123. /* #include "event1.c"  */
  124. /* gets the event handler */
  125. /* event1.c */
  126. HandleEvent(code)
  127.         LONG code;      /* provided by main */
  128. {
  129.         switch(code)
  130.         {
  131.         case CLOSEWINDOW:
  132.                 return(0);
  133.                 break;
  134.         case INTUITICKS:        /* could have done much faster
  135.                                  * but what the heck, this is
  136.                                  * shorter for test purposes
  137.                                  */
  138.                 movesprites();  /* 10 moves per second; test */
  139.                 default:
  140.                         break;
  141.         }
  142. return(1);
  143. }
  144. UWORD mycolortable[] = {
  145.         0x0000, 0x0e30, 0x0fff, 0x0b40, 0x0fb0, 0x0bf0,
  146.         0x05d0, 0x0ed0, 0x07df, 0x069f, 0x0c0e,
  147.         0x0f2e, 0x0feb, 0x0c98, 0x0bbb, 0x07df,
  148.         0x0000, 0x0e30, 0x0fff, 0x0b40,
  149.         0x0fb0, 0x0bf0, 0x05d0, 0x0ed0,
  150.         0x07df, 0x069f, 0x0c0e, 0x0f2e,
  151.         0x0feb, 0x0c98, 0x0bbb, 0x07df
  152.         };
  153.         /* black, red, white, fire-engine red, orange, yellow,
  154.         lime green, green, aqua, dark blue, purple,
  155.         violet, tan, brown, gray, skyblue, (everything again) */
  156. UWORD colorset0[ ] = { 0x0e30, 0xffff, 0x0b40 }; /* same as colors 17-19 */
  157. UWORD colorset1[ ] = { 0x0bf0, 0x05d0, 0x0ed0 }; /* 21-23 */
  158. UWORD colorset2[ ] = { 0x069f, 0x0c0e, 0x0f2e }; /* 25-27 */
  159. UWORD colorset3[ ] = { 0x0c98, 0x0bbb, 0x07df }; /* 29-31 */
  160. UWORD *colorset[ ] = {
  161.                         colorset0, colorset1,
  162.                         colorset2, colorset3 };
  163. int choice;
  164. char *numbers[] = { "17","18","19",
  165.                     "20","21","22","23",
  166.                     "24","25","26","27",
  167.                     "28","29","30","31" };
  168. /* #include "ram:purgegels.c" */
  169. /* purgegels.c */
  170. /*
  171.  * Use this to get rid of the gels stuff when it is not needed any more.
  172.  * You must have allocated the gels info stuff (use the ReadyGels routine).
  173.  */
  174. PurgeGels(g)
  175. struct GelsInfo *g;
  176. {
  177.    if (g->collHandler != NULL)
  178.       FreeMem(g->collHandler, sizeof(struct collTable));
  179.    if (g->lastColor != NULL)
  180.       FreeMem(g->lastColor, sizeof(LONG) * 8);
  181.    if (g->nextLine != NULL)
  182.       FreeMem(g->nextLine, sizeof(WORD) * 8);
  183.    if (g->gelHead != NULL)
  184.       FreeMem(g->gelHead, sizeof(struct VSprite));
  185.    if (g->gelTail != NULL)
  186.       FreeMem(g->gelTail, sizeof(struct VSprite));
  187. }
  188. /* Deallocate memory which has been allocated by the routines Makexxx. */
  189. /* Assumes images and imageshadow deallocated elsewhere. */
  190. DeleteGel(v)
  191. struct VSprite *v;
  192. {
  193.    if (v != NULL) {
  194.       if (v->VSBob != NULL) {
  195.          if (v->VSBob->SaveBuffer != NULL) {
  196.             FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
  197.                   * v->Height * v->Depth);
  198.          }
  199.          if (v->VSBob->DBuffer != NULL) {
  200.             if (v->VSBob->DBuffer->BufBuffer != 0) {
  201.                FreeMem(v->VSBob->DBuffer->BufBuffer,
  202.                      sizeof(SHORT) * v->Width * v->Height * v->Depth);
  203.             }
  204.             FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
  205.          }
  206.          FreeMem( v->VSBob, sizeof(struct Bob));
  207.       }
  208.       if (v->CollMask != NULL) {
  209.          FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
  210.       }
  211.       if (v->BorderLine != NULL) {
  212.          FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
  213.       }
  214.       FreeMem(v, sizeof(struct VSprite));
  215.    }
  216. }
  217. /* end of purgegels.c */
  218. /* #include "ram:readygels.c" */
  219. /* readygels.c */
  220. struct VSprite *SpriteHead = NULL;
  221. struct VSprite *SpriteTail = NULL;
  222. void border_dummy()     /* a dummy collision routine */
  223. {
  224.    return;
  225. }
  226. ReadyGels(g, r)
  227. struct RastPort *r;
  228. struct GelsInfo *g;
  229. {
  230.    /* Allocate head and tail of list. */
  231.    if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
  232.          (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  233.    {
  234.       return(-1);
  235.    }
  236.    if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
  237.          (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  238.    {
  239.       FreeMem(SpriteHead, sizeof(struct VSprite));
  240.       return(-2);
  241.    }
  242.    g->sprRsrvd = 0xFC;  /* do not use sprites 0 or 1. */
  243.    if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
  244.          MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  245.    {
  246.       FreeMem(SpriteHead, sizeof(struct VSprite));
  247.       FreeMem(SpriteTail, sizeof(struct VSprite));
  248.       return(-3);
  249.    }
  250.  
  251.   if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
  252.          MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  253.    {
  254.       FreeMem(g->nextLine,8 * sizeof(WORD));
  255.       FreeMem(SpriteHead, sizeof(struct VSprite));
  256.       FreeMem(SpriteTail, sizeof(struct VSprite));
  257.       return(-4);
  258.    }
  259.   /* Next we prepare a table of pointers to the routines which should
  260.    * be performed when DoCollision senses a collision.  This
  261.    * declaration may not be necessary for a basic vsprite with
  262.    * no collision detection implemented, but then it makes for
  263.    * a complete example.
  264.    */
  265.    if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
  266.          collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  267.    {
  268.       FreeMem(g->lastColor, 8 * sizeof(LONG));
  269.       FreeMem(g->nextLine,8 * sizeof(WORD));
  270.       FreeMem(SpriteHead, sizeof(struct VSprite));
  271.       FreeMem(SpriteTail, sizeof(struct VSprite));
  272.       return(-5);
  273.    }
  274.   /* When any part of the object touches or passes across
  275.    * this boundary, it will cause the boundary collision
  276.    * routine to be called.  This is at smash[0] in the
  277.    * collision handler table and is called only if
  278.    * DoCollision is called.
  279.    */
  280.    g->leftmost = 0;
  281.    g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
  282.    g->topmost = 0;
  283.    g->bottommost = r->BitMap->Rows - 1;
  284.    r->GelsInfo = g;  /* Link together the two structures */
  285.    InitGels(SpriteHead, SpriteTail, g );
  286.   /* Pointers initialized to the dummy sprites which will be
  287.    * used by the system to keep track of the animation system.
  288.    */
  289.    SetCollision(0, border_dummy, g);
  290.    WaitTOF();
  291.    return(0);   /* a return value of 0 says all ok, any
  292.                  * negative value tells you when it failed.
  293.                  * (see the listing as to what the routine
  294.                  * was trying to do... all failures are
  295.                  * due to out of memory conditions).
  296.                  */
  297. }
  298. /* end of readygels.c */
  299. /* #include "ram:MakeVSprite.c" */
  300. /* MakeVSprite.c */
  301. struct VSprite *MakeVSprite(lineheight, image, colorset, x, y,
  302.                                 wordwidth, imagedepth, flags)
  303. SHORT lineheight;       /* How tall is this vsprite? */
  304. WORD *image;            /* Where is the vsprite image data, should be
  305.                            twice as many words as the value of lineheight */
  306. WORD *colorset;         /* Where is the set of three words which describes
  307.                            the colors that this vsprite can take on? */
  308. SHORT x, y;             /* What is its initial onscreen position? */
  309. SHORT wordwidth, imagedepth, flags;
  310. {
  311.    struct VSprite *v;   /* Make a pointer to the vsprite structure which
  312.                            this routine dynamically allocates */
  313.    if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
  314.          MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  315.    {
  316.       return(0);
  317.    }
  318.    v->Flags = flags;    /* Is this a vsprite, not a bob? */
  319.    v->Y = y;            /* Establish initial position relative to */
  320.    v->X = x;            /* the Display coordinates. */
  321.    v->Height = lineheight;      /* The Caller says how high it is. */
  322.    v->Width = wordwidth;   /* A vsprite is always 1 word (16 bits) wide. */
  323.   /* There are two kinds of depth... the depth of the image itself, and the
  324.    * depth of the playfield into which it will be drawn. The image depth
  325.    * says how much data space will be needed to store an image if it's
  326.    * dynamically allocated. The playfield depth establishes how much space
  327.    * will be needed to save and restore the background when a bob is drawn.
  328.    * A vsprite is always 2 planes deep, but if it's being used to make a
  329.    * bob, it may be deeper...
  330.    */
  331.    v->Depth = imagedepth;
  332.   /* Assume that the caller at least has a default boundary collision
  333.    * routine.... bit 1 of this mask is reserved for boundary collision
  334.    * detect during DoCollision(). The only collisions reported will be
  335.    * with the borders. The caller can change all this later.
  336.    */
  337.    v->MeMask = 1;
  338.    v->HitMask = 1;
  339.    v->ImageData = image;        /* Caller says where to find the image. */
  340.   /* Show system where to find a mask which is a squished down version
  341.    * of the vsprite (allows for fast horizontal border collision detect).
  342.    */
  343.    if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
  344.          MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  345.    {
  346.         FreeMem(v, sizeof(struct VSprite));
  347.         return(0);
  348.    }
  349.   /* Show system where to find the mask which contains a 1 bit for any
  350.    * position in the object in any plane where there is a 1 bit (all planes
  351.    * OR'ed together).
  352.    */
  353.    if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
  354.          MEMF_CHIP | MEMF_CLEAR)) == 0)
  355.    {
  356.         FreeMem(v, sizeof(struct VSprite));
  357.         FreeMem(v->BorderLine, wordwidth * sizeof(WORD));
  358.         return(0);
  359.    }
  360.   /* This isn't used for a Bob, just a VSprite. It's where the
  361.    * Caller says where to find the VSprites colors.
  362.    */
  363.    v->SprColors = colorset;
  364.    /* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
  365.    v->PlanePick  = 0x00;
  366.    v->PlaneOnOff = 0x00;
  367.    InitMasks(v);        /* Create the collMask and borderLine */
  368.    return(v);
  369. }
  370. /* end of MakeVSprite.c */
  371. main()
  372. {
  373.         struct IntuiMessage *msg;
  374.         LONG result;
  375.         SHORT k, j, x, y, error;
  376.         UWORD *src, *dest;      /* for copying sprite data to RAM */
  377.         GfxBase = OpenLibrary("graphics.library",0);
  378.         IntuitionBase = OpenLibrary("intuition.library",0);
  379.         /* (error checking left out for brevity here) */
  380.         s = OpenScreen(&myscreen1);  /* try to open it */
  381.         if(s == 0)
  382.         {
  383.                 printf("Can't open myscreen1\n");
  384.                 exit(10);
  385.         }
  386.         myWindow.Screen = s;    /* say where screen is located */
  387.         ShowTitle(s, FALSE);    /* Dont let screen be dragged down...*/
  388.         w = OpenWindow(&myWindow);
  389.         if(w == 0)
  390.         {
  391.                 printf("Window didn't open!\n");
  392.                 CloseScreen(s);
  393.                 exit(20);
  394.         }
  395.         vp = &(s->ViewPort);
  396.         /* set the colors for this viewport */
  397.         LoadRGB4(vp, &mycolortable[0], 32);
  398.         rp = w->RPort;
  399.                 /* Now wait for a message to arrive from Intuition
  400.                  * (task goes to sleep while waiting for the message)
  401.                  */
  402.         /* Write Text using sprite colors so that demo can show
  403.          * how the vsprite machine stuffs the colors as it goes
  404.          * down the screen.  Thus if using vsprites, user should
  405.          * avoid using the color registers that the vsprites use.
  406.          */
  407.         /* Notice also that color numbers 17-19 are untouched.
  408.          * That is because of the sprResrvd=0xFC in ReadyGels.
  409.          * (Doesn't allow the virtual sprite machine to access
  410.          * either sprite 0 or 1... 0 is used by mouse cursor and
  411.          * shares its colors with 1, so I reserved both of them.
  412.          */
  413.         for(j=8; j<180; j+=50)
  414.         {
  415.                 for(k=0; k<15; k++)
  416.                 {
  417.                         Move(rp,k*20,j);
  418.                         SetAPen(rp,k+17);       /* show 17-31 */
  419.                         /* 16, 20, 24, 28 are unaffected by vsprites
  420.                          * because they are not used by hardware sprites */
  421.                         Text(rp,numbers[k],2);
  422.                 }
  423.         }
  424.         /* *************************************** */
  425.         /* VSPRITE DEMO SECTION                    */
  426.         /* *************************************** */
  427.         /* Allocate CHIP memory to hold the actual sprite data */
  428.         /* (necessary if ever to run on an expanded RAM Amiga) */
  429.         sprdata = (UWORD *)AllocMem(36, MEMF_CHIP);
  430.         if(sprdata == NULL)
  431.         {
  432.                 /* not enough memory for sprite */
  433.         }
  434.         /* now copy the sprite data into the CHIP RAM. */
  435.         src = sprite_data;
  436.         dest = sprdata;         /* source, destination */
  437.         for( j=0; j<18; j++)
  438.         {
  439.                 *dest++ = *src++;
  440.         }
  441.         choice = 0;
  442.         maxgot = 0;
  443.         /* Prepare the GELS system to work with VSPRITE or BOBS */
  444.         error = ReadyGels(&mygelsinfo, rp);
  445.         for(k=0; k<MAXSP; k++)  /* whatever maximum number of vsprites */
  446.         {
  447.                 xmove[k]=speed[RangeRand(4)];
  448.                 ymove[k]=speed[RangeRand(4)];
  449.                 /* establish a position for the sprite */
  450.                 x = 10 + RangeRand(280);
  451.                 y = 10 + RangeRand(170);
  452.                 /* create a vsprite */
  453.                 vsprite[k] = MakeVSprite( 9, sprdata, colorset[choice],
  454.                                         x, y, 1, 2, VSPRITE);
  455.                 /* 9 lines high, using MEMF_CHIP image of a sprite,
  456.                  * with a particular set of colors, at an X,Y location
  457.                  * 1 word wide, 2 planes deep (all vsprites are 2 deep)
  458.                  * and it is a VSPRITE */
  459.                 if(vsprite[k] == 0)
  460.                 {
  461.                         break;  /* ran out of memory! */
  462.                 }
  463.                 AddVSprite(vsprite[k], rp);
  464.                 maxgot++;
  465.                 choice++; /* choose a different color set */
  466.                 if(choice >= 4)
  467.                 {
  468.                         choice = 0;     /* wrap around on colorsets */
  469.                 }
  470.         }
  471.         while(1)        /* forever */
  472.         {
  473.                 WaitTOF();
  474.                 movesprites();
  475.                 result = -1;    /* now see if CLOSEWINDOW is waiting */
  476.                 msg = (struct IntuiMessage *)GetMsg(w->UserPort);
  477.                 if(msg != 0)
  478.                 {
  479.                         result = HandleEvent(msg->Class);
  480.                         /* Let Intuition reuse the msg */
  481.                         ReplyMsg(msg);
  482.                 }
  483.                 if(result == 0)
  484.                 {
  485.                         break;  /* got a CLOSEWINDOW */
  486.                 }
  487.         }
  488.         /* DONE, now cleanup */
  489.         /* Free however many vsprites we actually managed to create */
  490.         for(k=0; k<maxgot; k++)
  491.         {
  492.                 DeleteGel(vsprite[k]);
  493.         }
  494.         /* delete what ReadyGels created */
  495.         PurgeGels(&mygelsinfo);
  496.         FreeMem(sprdata, 36);   /* free what we allocated. */
  497.         CloseWindow(w);
  498.         CloseScreen(s);
  499. }
  500.